﻿using Furion;
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Admin.NET.Core;
using Yitter.IdGenerator;
using StackExchange.Redis;

namespace Admin.NET.Application
{
    /// <summary>
    /// WCS调用服务
    /// </summary>
    [ApiDescriptionSettings("WCS调用服务", Name = "WareWcsToWmsService", Order = 100)]
    [Route("api/[Controller]")]
    public class WareWcsToWmsService : IDynamicApiController, ITransient
    {
        private readonly IRepository<WmsOrder, MasterDbContextLocator> _wmsOrderRep;
        private readonly IRepository<WmsOrderDetails, MasterDbContextLocator> _wmsOrderDetailsRep;
        private readonly IRepository<WmsTask, MasterDbContextLocator> _wmsTaskRep;
        private readonly IRepository<WmsMaterialContainer, MasterDbContextLocator> _wmsMaterialContainerRep;
        private readonly IRepository<WmsPlace, MasterDbContextLocator> _wmsPlaceRep;
        private readonly IRepository<WmsContainerPlace, MasterDbContextLocator> _wmsContainerPlaceRep;
        private readonly IRepository<WmsMaterialStock, MasterDbContextLocator> _wmsMaterialStockRep;
        private readonly IRepository<WmsContainer, MasterDbContextLocator> _wmsContainerRep;
        private readonly IRepository<LesPackWarehouse, MasterDbContextLocator> _lesPackWarehouseRep;
        private readonly IRepository<LesDeviceWaring, MasterDbContextLocator> _lesDeviceWaringRep;


        /// <summary>
        /// 构造函数
        /// </summary>
        public WareWcsToWmsService(
            IRepository<WmsOrder, MasterDbContextLocator> wmsOrderRep,
            IRepository<WmsOrderDetails, MasterDbContextLocator> wmsOrderDetailsRep,
            IRepository<WmsTask, MasterDbContextLocator> wmsTaskRep,
            IRepository<WmsMaterialContainer, MasterDbContextLocator> wmsMaterialContainerRep,
            IRepository<WmsPlace, MasterDbContextLocator> wmsPlaceRep,
            IRepository<WmsContainerPlace, MasterDbContextLocator> wmsContainerPlaceRep,
            IRepository<WmsMaterialStock, MasterDbContextLocator> wmsMaterialStockRep,
            IRepository<WmsContainer, MasterDbContextLocator> wmsContainerRep,
            IRepository<LesPackWarehouse, MasterDbContextLocator> lesPackWarehouseRep,
            IRepository<LesDeviceWaring, MasterDbContextLocator> lesDeviceWaringRep
        )
        {
            _wmsOrderRep = wmsOrderRep;
            _wmsOrderDetailsRep = wmsOrderDetailsRep;
            _wmsTaskRep = wmsTaskRep;
            _wmsMaterialContainerRep = wmsMaterialContainerRep;
            _wmsPlaceRep = wmsPlaceRep;
            _wmsContainerPlaceRep = wmsContainerPlaceRep;
            _wmsMaterialStockRep = wmsMaterialStockRep;
            _wmsContainerRep = wmsContainerRep;
            _lesPackWarehouseRep = lesPackWarehouseRep;
            _lesDeviceWaringRep = lesDeviceWaringRep;
        }


        /// <summary>
        /// 定时查询WCS可以下发的出入库任务(10条)
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetSendTask")]
        [AllowAnonymous]
        public async Task<List<SendTaskDetailOutput>> GetSendTask()
        {
            var outputList = new List<SendTaskDetailOutput>();
            var alllist = await _wmsTaskRep.DetachedEntities
                .Where(z => z.IsRead == true)
                .Take(10)
                .OrderByDescending(n => n.TaskLevel)
                .OrderBy(p => p.CreatedTime).ToListAsync();
            foreach (var item in alllist)
            {
                var sendTaskDetail = new SendTaskDetailOutput(); //任务详情
                sendTaskDetail.TaskNo = item.TaskNo;
                if (item.TaskType == TaskType.RUKU) sendTaskDetail.SourcePlace = item.ToPlace;
                else sendTaskDetail.SourcePlace = item.SourcePlace;
                sendTaskDetail.Aisle = item.Aisle;
                sendTaskDetail.TaskType = item.TaskType;
                sendTaskDetail.TaskLevel = item.TaskLevel;
                sendTaskDetail.ContainerCode = item.ContainerCode;
                sendTaskDetail.TaskStatus = item.TaskStatus;
                outputList.Add(sendTaskDetail);

                //item.IsRead=false;
                //item.TaskStatus = TaskStatusEnum.DAIZHIXING;
                //await _wmsTaskRep.UpdateAsync(item);
            }
            return outputList;
        }


        /// <summary>
        /// 更新任务信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("UpdateTask")]
        [UnitOfWork]
        [AllowAnonymous]
        public async Task UpdateTask([FromBody] UpdateTaskInput input)
        {
            //根据任务号查询任务信息
            var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(z => z.TaskNo == input.TaskNo);
            if (wmsTask == null) throw Oops.Oh(errorMessage: "任务不存在！");
            wmsTask.TaskDodeviceStatus = input.TaskDodeviceStatus;
            wmsTask.TaskStatus = TaskStatusEnum.ZHIXINGZHONG;
            wmsTask.IsRead = false;

            WmsPlace wmsPlace = new WmsPlace();
            //判断入库还是出库
            if (wmsTask.TaskType == TaskType.RUKU)
            {
                //库位信息
                wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(z => z.PlaceCode == wmsTask.ToPlace);
            }
            else if (wmsTask.TaskType == TaskType.CHUKU)
            {
                //库位信息
                wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(z => z.PlaceCode == wmsTask.SourcePlace);
            }
            if (wmsPlace == null) throw Oops.Oh(errorMessage: "库位不存在！");

            // 查询托盘信息
            var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode);
            if (wmsContainer == null) throw Oops.Oh("托盘不存在！");

            //入库称重
            //if (wmsTask.TaskType == TaskType.RUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.ZX_RKCZ)
            //{
            //}
            //入库输送线开始
            //if (wmsTask.TaskType == TaskType.RUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.ZX_RSSX)
            //{
            //}
            //入库输送线结束
            //if (wmsTask.TaskType == TaskType.RUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.WC_RSSX)
            //{
            //}
            //入库RGV开始
            //if (wmsTask.TaskType == TaskType.RUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.ZX_RGV)
            //{
            //}
            //入库RGV结束
            //if (wmsTask.TaskType == TaskType.RUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.WC_RGV)
            //{
            //}
            //入库开始
            if (wmsTask.TaskType == TaskType.RUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.ZX_DDJ)
            {
                // 更新库位状态
                wmsPlace.PlaceStatus = PlaceStatus.DAIRU;
                await _wmsPlaceRep.UpdateAsync(wmsPlace);
            }
            //入库完成
            if (wmsTask.TaskType == TaskType.RUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.WC_DDJ)
            {
                //首先更新任务状态完成
                wmsTask.TaskStatus = TaskStatusEnum.WANCHENG;
                //更新设备状态
                wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.W;

                // 更新托盘状态为“库位”
                wmsContainer.ContainerStatus = ContainerStatus.KUWEI;
                await _wmsContainerRep.UpdateAsync(wmsContainer);

                //库位信息
                if (wmsPlace == null) throw Oops.Oh("库位不存在!");
                if (wmsPlace.Islock == YesOrNot.Y) throw Oops.Oh("库位被锁定!");

                // 更新库位状态为“存货”
                wmsPlace.PlaceStatus = PlaceStatus.CUNHUO;
                if (wmsTask.Description == "空托") wmsPlace.EmptyContainer = YesOrNot.Y;
                else wmsPlace.EmptyContainer = YesOrNot.N;
                await _wmsPlaceRep.UpdateAsync(wmsPlace);

                // 创建托盘号库位关系表
                var wmsContainerPlaceModel = new WmsContainerPlace()
                {
                    PlaceId = wmsPlace.Id,
                    PlaceCode = wmsPlace.PlaceCode,
                    ContainerId = wmsContainer.Id,
                    ContainerCode = wmsContainer.ContainerCode,
                    ContainerPlaceStatus = CommonStatus.ENABLE
                };
                await _wmsContainerPlaceRep.InsertAsync(wmsContainerPlaceModel);

                // 更新库存
                var wmsMaterialContainerList = await _wmsMaterialContainerRep.DetachedEntities
                    .Where(p => p.OrderNo == wmsTask.OrderNo && p.BindStatus == CommonStatus.ENABLE).ProjectToType<WmsMaterialContainer>().ToListAsync();

                foreach (var item in wmsMaterialContainerList)
                {
                    var wmsMaterialStock = await _wmsMaterialStockRep.FirstOrDefaultAsync(p => p.ContainerCode == wmsContainer.ContainerCode
                    && p.MaterialBatch == item.MaterialBatch);
                    if (wmsMaterialStock != null)
                    {
                        wmsMaterialStock.Source = RuKuSourceEnum.WULIAO;
                        wmsMaterialStock.AreaId = wmsPlace.AreaId;
                        wmsMaterialStock.PlaceCode = wmsPlace.PlaceCode;
                        wmsMaterialStock.StockNumber = item.BindQuantity;
                        await _wmsMaterialStockRep.UpdateAsync(wmsMaterialStock);
                    }
                    else
                    {
                        wmsMaterialStock = new WmsMaterialStock()
                        {
                            InspectionMethod = MaterialInspection.MIANJIAN,
                            UnitType = UnitType.ZHONGLIANG,
                            UnitNo = UnitNoType.T,
                            MaterialNo = item.MaterialNo,
                            MaterialType = MaterialType.CHENGPING,
                            MaterialName = item.MaterialName,
                            MaterialSpec = item.MaterialSpec,
                            MaterialBatch = item.MaterialBatch,
                            MaterialDensity = item.MaterialDensity,
                            StockNumber = item.BindQuantity,
                            PlaceCode = wmsPlace.PlaceCode,
                            ContainerId = wmsContainer.Id,
                            ContainerCode = wmsContainer.ContainerCode,
                            AreaId = wmsPlace.AreaId,
                            Source = RuKuSourceEnum.WULIAO
                        };
                        await _wmsMaterialStockRep.InsertAsync(wmsMaterialStock);
                    }
                }
                // 空料箱入库
                if (wmsTask.Description == "空托")
                {
                    var wmsMaterialStock = new WmsMaterialStock()
                    {
                        InspectionMethod = MaterialInspection.MIANJIAN,
                        UnitType = UnitType.ZHONGLIANG,
                        UnitNo = UnitNoType.T,
                        MaterialNo = "N/A",
                        MaterialType = MaterialType.KONGTUO,
                        MaterialName = "N/A",
                        MaterialSpec = "N/A",
                        MaterialBatch = "N/A",
                        MaterialDensity = "N/A",
                        StockNumber = 0,
                        PlaceCode = wmsPlace.PlaceCode,
                        ContainerId = wmsContainer.Id,
                        ContainerCode = wmsContainer.ContainerCode,
                        AreaId = wmsPlace.AreaId,
                        Source = RuKuSourceEnum.KONGTUO
                    };
                    await _wmsMaterialStockRep.InsertAsync(wmsMaterialStock);
                }
            }
            //出库堆垛机完成,执行库存，库位，托盘对应关系进行更新
            else if (wmsTask.TaskType == TaskType.CHUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.WC_DDJ)
            {

                if (wmsPlace == null) throw Oops.Oh("库位不存在!");
                if (wmsPlace.PlaceStatus != PlaceStatus.DAICHU) throw Oops.Oh("库位异常货!");

                // 查询托盘与库位的关系
                var wmsContainerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(z => z.PlaceId == wmsPlace.Id && z.PlaceCode == wmsPlace.PlaceCode
                && z.ContainerCode == wmsTask.ContainerCode && z.ContainerPlaceStatus == CommonStatus.ENABLE);
                if (wmsContainerPlace == null) throw Oops.Oh("库位容器关系不存在!");

                // 查询库存信息
                var wmsMaterialStockList = await _wmsMaterialStockRep.DetachedEntities.Where(u => u.ContainerCode == wmsTask.ContainerCode).ToListAsync();
                if (wmsMaterialStockList.Count <= 0) throw Oops.Oh("库存数据异常!");

                ////查询物料与托盘组盘关系（状态：正常）
                var wmsMaterialContainerList = await _wmsMaterialContainerRep.Where(p => p.ContainerCode == wmsTask.ContainerCode
                    && p.BindStatus == CommonStatus.ENABLE && p.OrderNo == wmsTask.OrderNo).ToListAsync();
                //判断物料是否是空托，如果是空托直接删除，不是空托查询物料
                if (wmsMaterialContainerList.Count == 0)
                {
                    //删除库存
                    foreach (var item in wmsMaterialStockList)
                    {
                        await _wmsMaterialStockRep.DeleteAsync(item);
                    }
                    // 更新托盘状态为“空闲”
                    wmsContainer.ContainerStatus = ContainerStatus.KOUXIAN;

                }
                else
                {
                    //构建出库物料和周转箱号关系
                    var orderNo = "N/A";
                    if (wmsMaterialContainerList.Count > 0) orderNo = YitIdHelper.NextId().ToString();
                    foreach (var item in wmsMaterialContainerList)
                    {
                        //更新状态为”删除“
                        item.BindStatus = CommonStatus.DELETED;
                        await _wmsMaterialContainerRep.UpdateNowAsync(item);

                        //新增组盘绑定记录 正常
                        var wmsMaterialContainer = item;
                        wmsMaterialContainer.Id = YitIdHelper.NextId();
                        wmsMaterialContainer.OrderNo = orderNo;
                        wmsMaterialContainer.BindStatus = CommonStatus.ENABLE;
                        await _wmsMaterialContainerRep.InsertNowAsync(wmsMaterialContainer);
                        //更改库存的库位号为N/A
                        foreach (var stock in wmsMaterialStockList)
                        {
                            stock.PlaceCode = "N/A";
                            await _wmsMaterialStockRep.UpdateAsync(stock);
                        }
                    }
                    wmsContainer.ContainerStatus = ContainerStatus.FENJIAN;
                }
                await _wmsContainerRep.UpdateAsync(wmsContainer);

                //更新库位状态为“空闲”
                wmsPlace.PlaceStatus = PlaceStatus.KONGXIAN;
                wmsPlace.Islock = YesOrNot.N;
                wmsPlace.EmptyContainer = YesOrNot.N;
                await _wmsPlaceRep.UpdateAsync(wmsPlace);

                //更新周转箱号与库位关系为“删除”
                wmsContainerPlace.ContainerPlaceStatus = CommonStatus.DELETED;
                await _wmsContainerPlaceRep.UpdateAsync(wmsContainerPlace);
            }
            if (wmsTask.TaskType == TaskType.CHUKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.WC_CSSX)
            {
                wmsTask.TaskStatus = TaskStatusEnum.WANCHENG;
                wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.W;
            }
            else //移库
            {
                if (wmsTask.TaskType == TaskType.YIKU && input.TaskDodeviceStatus == TaskDodeviceStatusEnum.WC_DDJ)
                {
                    wmsTask.TaskStatus = TaskStatusEnum.WANCHENG;
                    wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.W;
                    // 起点库位信息
                    var SourcePlace = await _wmsPlaceRep.Where(z => z.PlaceCode == wmsTask.SourcePlace).FirstOrDefaultAsync();
                    SourcePlace.PlaceStatus = PlaceStatus.KONGXIAN;
                    await _wmsPlaceRep.UpdateAsync(SourcePlace);
                    //目标库位信息
                    var ToPlace = await _wmsPlaceRep.Where(z => z.PlaceCode == wmsTask.ToPlace).FirstOrDefaultAsync();
                    ToPlace.PlaceStatus = PlaceStatus.CUNHUO;
                    await _wmsPlaceRep.UpdateAsync(ToPlace);
                    //托盘库位关系表
                    var wmsContainerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(z => z.PlaceId == SourcePlace.Id && z.PlaceCode == SourcePlace.PlaceCode
                    && z.ContainerCode == wmsTask.ContainerCode && z.ContainerPlaceStatus == CommonStatus.ENABLE);
                    wmsContainerPlace.ContainerPlaceStatus = CommonStatus.DELETED;
                    await _wmsContainerPlaceRep.UpdateAsync(wmsContainerPlace);
                    await _wmsContainerPlaceRep.InsertAsync(new WmsContainerPlace()
                    {
                        PlaceId = ToPlace.Id,
                        PlaceCode = ToPlace.PlaceCode,
                        ContainerId = wmsContainer.Id,
                        ContainerCode = wmsContainer.ContainerCode,
                        ContainerPlaceStatus = CommonStatus.ENABLE
                    });
                    //库存库位更新
                    var stockModel = await _wmsMaterialStockRep.Where(p => p.ContainerCode == wmsTask.ContainerCode && p.PlaceCode == SourcePlace.PlaceCode).FirstOrDefaultAsync();
                    if (stockModel != null)
                    {
                        stockModel.PlaceCode = ToPlace.PlaceCode;
                    }
                }
            }
            await _wmsTaskRep.UpdateAsync(wmsTask);
        }

        /// <summary>
        /// 获取库位信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("GetPlace")]
        [AllowAnonymous]
        public async Task<GetPlaceOutput> GetPlace([FromBody] GetPlaceInput input)
        {
            //1.列 优先1排和4排 层优先从下到上
            //2.保留10个内侧移库库位 
            var taskModel = await _wmsTaskRep.Where(p => p.TaskNo == input.TaskNo).FirstOrDefaultAsync();
            if (taskModel == null) return new GetPlaceOutput() { TaskIsExist = false };
            if (taskModel.TaskStatus == TaskStatusEnum.CHEHUI || taskModel.TaskStatus == TaskStatusEnum.QUXIAO || taskModel.TaskStatus == TaskStatusEnum.WANCHENG || taskModel.TaskStatus == TaskStatusEnum.ZANTING)
            {
                throw Oops.Oh("任务状态未满足获取的库位条件");
            }
            taskModel.TaskStatus = TaskStatusEnum.ZHIXINGZHONG;
            //定义入库对象,移库对象
            var ToPlace = new WmsPlace();
            var SourcePlace = new WmsPlace();
            var rowNumber = 0;

            //入库流程
            if (taskModel.TaskType == TaskType.RUKU)
            {
                //防重操作
                if (taskModel != null && !string.IsNullOrEmpty(taskModel.ToPlace))
                {
                    ToPlace = await _wmsPlaceRep.Where(p => p.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN && p.PlaceCode == taskModel.ToPlace).FirstOrDefaultAsync();
                    if (ToPlace.RowNo == GetOneRowByAisle(taskModel.Aisle) || ToPlace.RowNo == GetFourRowByAisle(taskModel.Aisle))
                    {
                        if (ToPlace.RowNo == GetOneRowByAisle(taskModel.Aisle))
                            rowNumber = GetTwoRowByAisle(taskModel.Aisle);
                        else
                            rowNumber = GetThreeRowByAisle(taskModel.Aisle);
                        SourcePlace = await _wmsPlaceRep.Where(p => p.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN && p.Aisle == taskModel.Aisle && p.RowNo == rowNumber && p.ColumnNo == ToPlace.ColumnNo && p.LayerNo == ToPlace.LayerNo).FirstOrDefaultAsync();
                        if (SourcePlace != null && SourcePlace.PlaceStatus == PlaceStatus.CUNHUO)
                            return new GetPlaceOutput() { ToPlace = ToPlace.PlaceCode, SourcePlace = SourcePlace.PlaceCode };
                    }
                    return new GetPlaceOutput() { ToPlace = ToPlace.PlaceCode };
                }
                //获取立体库可用库位
                var placeList = await _wmsPlaceRep.DetachedEntities.Where(z => z.PlaceStatus == PlaceStatus.KONGXIAN
                && z.Islock == YesOrNot.N && z.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN
                && z.WmsArea.AreaType == AreaType.LITIKU && z.Aisle == taskModel.Aisle).ProjectToType<WmsPlace>().ToListAsync();

                //获取当前立体库需要出库库位集合
                var placeCodeList = await _wmsTaskRep.DetachedEntities.Where(p => p.IsRead == true
                && p.TaskType == TaskType.CHUKU && p.Aisle == taskModel.Aisle).Select(n => n.SourcePlace).ToListAsync();

                var ckPlaceModelList = await _wmsPlaceRep.DetachedEntities.Where(z => placeCodeList.Contains(z.PlaceCode)
                && z.Islock == YesOrNot.N && z.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN
                && z.WmsArea.AreaType == AreaType.LITIKU && z.Aisle == taskModel.Aisle).ToListAsync();

                //配置文件中设置是否开启指定库位入库和移库操作
                //if (Convert.ToBoolean(App.Configuration["YiKuTestPalce:IsStart"]))
                //{
                //    var rukuPoint = App.Configuration["YiKuTestPalce:rukuPoint"].Split('.');  //入库起点
                //    var yikuPoint = App.Configuration["YiKuTestPalce:yikuPoint"].Split('.');  //移库起点
                //    ToPlace = placeList.Where(p => p.RowNo == Convert.ToInt32(rukuPoint[0])
                //    && p.ColumnNo == Convert.ToInt32(rukuPoint[1]) && p.LayerNo == Convert.ToInt32(rukuPoint[2])).FirstOrDefault();
                //    if (ToPlace != null)
                //    {
                //        ToPlace.PlaceStatus = PlaceStatus.DAIRU;
                //        await _wmsPlaceRep.UpdateAsync(ToPlace);
                //        taskModel.ToPlace = ToPlace.PlaceCode;
                //        taskModel.AreaName = ToPlace.WmsArea.AreaName;
                //        await _wmsTaskRep.UpdateAsync(taskModel);
                //        if (yikuPoint.Length > 1)
                //        {
                //            SourcePlace = await _wmsPlaceRep.FirstOrDefaultAsync(p => p.RowNo == Convert.ToInt32(yikuPoint[0])
                //            && p.ColumnNo == Convert.ToInt32(yikuPoint[1]) && p.LayerNo == Convert.ToInt32(yikuPoint[2])
                //            && p.Aisle == taskModel.Aisle && p.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN
                //            && p.WmsArea.AreaType == AreaType.LITIKU
                //            );
                //        }
                //        return new GetPlaceOutput() { ToPlace = ToPlace.PlaceCode, SourcePlace = SourcePlace.PlaceCode };
                //    }
                //}
                var maxColumn = placeList.Max(selector: n => n.ColumnNo);
                var maxLayerNo = 0;

                //先以列为进行循环判断
                for (int j = 1; j <= maxColumn; j++)
                {
                    //获取该列的最大层
                    if (placeList.Where(p => p.ColumnNo == j).Count() <= 1) continue;
                    maxLayerNo = placeList.Where(p => p.ColumnNo == j).Max(selector: n => n.LayerNo);
                    //循环每列每层的中列
                    //分配库位需要考虑外侧是否有出库任务，有的话就没有执行
                    for (int f = 1; f <= maxLayerNo; f++)
                    {

                        var model = placeList.FirstOrDefault(p => p.RowNo == GetOneRowByAisle(taskModel.Aisle) && p.ColumnNo == j && p.LayerNo == f);
                        var ckmodel = ckPlaceModelList.FirstOrDefault(p => p.RowNo == GetTwoRowByAisle(taskModel.Aisle) && p.ColumnNo == j && p.LayerNo == f);
                        if (model != null && ckmodel == null)
                        {
                            ToPlace = model;
                            break;
                        }
                    }
                    if (!string.IsNullOrEmpty(ToPlace.PlaceCode)) break;
                }
                if (string.IsNullOrEmpty(ToPlace.PlaceCode)) throw Oops.Oh("暂无可以库位!");

                //进行库位和任务的更新
                ToPlace.PlaceStatus = PlaceStatus.DAIRU;
                await _wmsPlaceRep.UpdateAsync(ToPlace);
                taskModel.ToPlace = ToPlace.PlaceCode;
                taskModel.AreaName = ToPlace.WmsArea.AreaName;
                await _wmsTaskRep.UpdateAsync(taskModel);
                if (SourcePlace == null || string.IsNullOrEmpty(SourcePlace.PlaceCode)) return new GetPlaceOutput() { ToPlace = ToPlace.PlaceCode };
                else return new GetPlaceOutput() { ToPlace = ToPlace.PlaceCode, SourcePlace = SourcePlace.PlaceCode };
            }
            //出库流程
            if (taskModel.TaskType == TaskType.CHUKU)
            {
                //需要判断下库位是否已经进行移库操作，需要通过托盘编号进行重新查找
                var containerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(p => p.ContainerCode == taskModel.ContainerCode
                && p.ContainerPlaceStatus == CommonStatus.ENABLE);
                if (containerPlace != null && containerPlace.PlaceCode != taskModel.SourcePlace)
                {
                    ToPlace = await _wmsPlaceRep.FirstOrDefaultAsync(p => p.PlaceCode == containerPlace.PlaceCode);
                    taskModel.SourcePlace = containerPlace.PlaceCode;
                }
                else
                {
                    ToPlace = await _wmsPlaceRep.FirstOrDefaultAsync(p => p.PlaceCode == taskModel.SourcePlace);
                }
                //进行库位和任务的更新
                ToPlace.PlaceStatus = PlaceStatus.DAICHU;
                await _wmsPlaceRep.UpdateAsync(ToPlace);
                taskModel.ToPlace = taskModel.Aisle.ToString();
                await _wmsTaskRep.UpdateAsync(taskModel);
                if (SourcePlace == null || string.IsNullOrEmpty(SourcePlace.PlaceCode)) return new GetPlaceOutput() { ToPlace = ToPlace.PlaceCode };
                else return new GetPlaceOutput() { ToPlace = ToPlace.PlaceCode, SourcePlace = SourcePlace.PlaceCode };
            }
            else
            {
                throw Oops.Oh("任务异常" + taskModel.TaskNo);
            }
        }


        /// <summary>
        /// 创建移库任务
        /// </summary>
        /// <returns></returns>
        [HttpPost("CreateYKTask")]
        [UnitOfWork]
        [AllowAnonymous]
        public async Task<GetYiKuPlaceOutput> CreateRelocation(CreateRelocationInput input)
        {
            var placeModel = await _wmsPlaceRep.Where(p => p.PlaceCode == input.SourcePlace).ProjectToType<WmsPlace>().FirstOrDefaultAsync();
            if (placeModel == null) throw Oops.Oh("库位数据异常!");
            placeModel.PlaceStatus = PlaceStatus.DAICHU;
            await _wmsPlaceRep.UpdateAsync(placeModel);
            //查询组盘单据
            var containerPlaceModel = await _wmsContainerPlaceRep.Where(p => p.PlaceCode == input.SourcePlace && p.ContainerPlaceStatus == CommonStatus.ENABLE).FirstOrDefaultAsync();
            if (containerPlaceModel == null) throw Oops.Oh("移库库位托盘数据异常!");
            var materialContainer = await _wmsMaterialContainerRep.Where(p => p.ContainerCode == containerPlaceModel.ContainerCode && p.BindStatus == CommonStatus.ENABLE).FirstOrDefaultAsync();
            if (materialContainer == null) throw Oops.Oh("组盘数据异常!");

            //获取空闲库位集合
            var placeList = await _wmsPlaceRep.DetachedEntities.Where(z => z.PlaceStatus == PlaceStatus.KONGXIAN
            && z.Islock == YesOrNot.N && z.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN
            && z.WmsArea.AreaType == AreaType.LITIKU && z.Aisle == input.Aisle).ToListAsync();
            if (placeList.Count == 0) throw Oops.Oh("无可移库库位!");

            //定义目标点
            var ToPlaceModel = new WmsPlace();
            var rowNumber = 0;
            //1.推荐外侧库位
            var wcPlaceList = placeList.Where(p => (p.RowNo == GetOneRowByAisle(placeModel.Aisle) || p.RowNo == GetFourRowByAisle(placeModel.Aisle))).ToList();
            if (placeModel.Aisle == 11)
            {
                wcPlaceList = placeList.Where(p => (p.RowNo == GetOneRowByAisle(placeModel.Aisle) || p.RowNo == GetThreeRowByAisle(placeModel.Aisle))).ToList();
            }
            //定义最优库位集合
            var zyPlaceList = new List<WmsPlace>();
            //循环判断对应的2,3是有货
            foreach (var item in wcPlaceList)
            {
                if (placeModel.Aisle == 11)
                {
                    if (item.RowNo == GetOneRowByAisle(placeModel.Aisle))
                    {
                        zyPlaceList.Add(item);
                    }
                    if (item.RowNo == GetThreeRowByAisle(placeModel.Aisle))
                    {
                        rowNumber = GetTwoRowByAisle(placeModel.Aisle);
                        var dypalceModel = placeList.Where(p => p.RowNo == rowNumber && p.ColumnNo == item.ColumnNo && p.LayerNo == item.LayerNo).FirstOrDefault();
                        if (dypalceModel != null)
                            zyPlaceList.Add(item);
                    }
                }
                else
                {
                    if (item.RowNo == GetOneRowByAisle(placeModel.Aisle) || item.RowNo == GetFourRowByAisle(placeModel.Aisle))
                    {
                        if (item.RowNo == GetOneRowByAisle(placeModel.Aisle))
                            rowNumber = GetTwoRowByAisle(placeModel.Aisle);
                        else
                            rowNumber = GetThreeRowByAisle(placeModel.Aisle);
                        var dypalceModel = placeList.Where(p => p.RowNo == rowNumber && p.ColumnNo == item.ColumnNo && p.LayerNo == item.LayerNo).FirstOrDefault();
                        if (dypalceModel != null)
                            zyPlaceList.Add(item);
                    }
                }
            }
            if (zyPlaceList.Count != 0)
            {
                //获取路径最短的库位 使用二分法
                var mindModel = zyPlaceList.Where(p => p.ColumnNo == placeModel.ColumnNo).FirstOrDefault();
                var leftModel = zyPlaceList.Where(p => p.ColumnNo < placeModel.ColumnNo).OrderByDescending(p => p.ColumnNo).FirstOrDefault();
                var rightModel = zyPlaceList.Where(p => p.ColumnNo > placeModel.ColumnNo).OrderBy(p => p.ColumnNo).FirstOrDefault();

                if (mindModel != null) ToPlaceModel = mindModel;
                else if (leftModel == null) ToPlaceModel = rightModel;
                else if (rightModel == null) ToPlaceModel = leftModel;
                else if ((placeModel.ColumnNo - leftModel.ColumnNo) > (rightModel.ColumnNo - placeModel.ColumnNo)) ToPlaceModel = rightModel;
                else ToPlaceModel = leftModel;
            }
            if (string.IsNullOrEmpty(ToPlaceModel.PlaceCode))
            {
                //2.次优库位集合
                //次优2,3排库位
                var cyPlace = placeList.Where(p => (p.RowNo == GetTwoRowByAisle(placeModel.Aisle) || p.RowNo == GetThreeRowByAisle(placeModel.Aisle))).OrderByDescending(p => p.ColumnNo).OrderBy(p => p.LayerNo).ToList();
                if (placeModel.Aisle == 11)
                {
                    cyPlace = placeList.Where(p => p.RowNo == GetTwoRowByAisle(placeModel.Aisle)).OrderByDescending(p => p.ColumnNo).OrderBy(p => p.LayerNo).ToList();
                }
                if (cyPlace.Count > 0)
                {
                    //获取路径最短的库位 使用二分法
                    var mindModel = cyPlace.Where(p => p.ColumnNo == placeModel.ColumnNo).OrderByDescending(p => p.ColumnNo).FirstOrDefault();
                    var leftModel = cyPlace.Where(p => p.ColumnNo < placeModel.ColumnNo).OrderByDescending(p => p.ColumnNo).FirstOrDefault();
                    var rightModel = cyPlace.Where(p => p.ColumnNo > placeModel.ColumnNo).OrderBy(p => p.ColumnNo).FirstOrDefault();

                    if (mindModel != null) ToPlaceModel = mindModel;
                    else if (leftModel == null) ToPlaceModel = rightModel;
                    else if (rightModel == null) ToPlaceModel = leftModel;
                    else if ((placeModel.ColumnNo - leftModel.ColumnNo) > (rightModel.ColumnNo - placeModel.ColumnNo)) ToPlaceModel = rightModel;
                    else ToPlaceModel = leftModel;
                }
            }
            ToPlaceModel.PlaceStatus = PlaceStatus.DAIRU;
            await _wmsPlaceRep.UpdateAsync(ToPlaceModel);

            //创建移库任务
            var newWmsTask = new WmsTask()
            {
                //TaskNo = _commonOrderServiceRep.GetFYKOrderNo(),
                TaskNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(),
                TaskModel = TaskModel.QUANZIDONG,
                TaskType = TaskType.YIKU,
                TaskLevel = 5,
                TaskStatus = TaskStatusEnum.WEIZHIXING,
                OrderNo = materialContainer.OrderNo,
                OrderDetailsId = materialContainer.OrderDetailsId,
                ContainerCode = materialContainer.ContainerCode,
                SourcePlace = placeModel.PlaceCode,
                ToPlace = ToPlaceModel.PlaceCode,
                AreaName = placeModel.WmsArea.AreaName,
                IsRead = true, //WCS是否可以读取
                SendTimes = 1, //发送次数
                Aisle = placeModel.Aisle,
                Dodevicetype = DodeviceType.AGV,
                TaskDodeviceStatus = TaskDodeviceStatusEnum.WZX,
            };
            await _wmsTaskRep.InsertAsync(newWmsTask);

            return new GetYiKuPlaceOutput()
            {
                ToPlace = ToPlaceModel.PlaceCode,
                TaskNo = newWmsTask.TaskNo,
            };
        }


        ///// <summary>
        ///// 强制完成
        ///// </summary>
        ///// <returns></returns>
        //[HttpPost("Finish")]
        //[UnitOfWork]
        //[AllowAnonymous]
        //public async Task Finish([FromBody] FinishTaskInput input)
        //{
        //    var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.TaskNo == input.TaskNo);
        //    if (wmsTask == null) throw Oops.Oh("任务不存在！");
        //    if (wmsTask.TaskStatus == TaskStatusEnum.WANCHENG) throw Oops.Oh("任务已完成，强制完成失败！");
        //    var statusList = new List<TaskStatusEnum> { TaskStatusEnum.WEIZHIXING, TaskStatusEnum.ZHIXINGZHONG };
        //    if (!statusList.Contains(wmsTask.TaskStatus)) throw Oops.Oh("只有未执行和执行中的任务才能强制完成！");

        //    if (wmsTask.TaskType == TaskType.RUKU) // 入库任务
        //    {
        //        var taskStatusList = new List<TaskDodeviceStatusEnum> { TaskDodeviceStatusEnum.ZX_DDJ, TaskDodeviceStatusEnum.WC_DDJ };
        //        if (!taskStatusList.Contains(wmsTask.TaskDodeviceStatus)) throw Oops.Oh("只有堆垛机执行,堆垛机完成才能强制完成！");
        //        //查询库位
        //        var wmsPlace = await _wmsPlaceRep.DetachedEntities.Where(u => u.PlaceCode == wmsTask.ToPlace
        //                && u.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN).ProjectToType<WmsPlace>().FirstOrDefaultAsync();
        //        // 查询托盘
        //        var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode);
        //        if (wmsContainer == null) throw Oops.Oh("托盘信息不存在!");
        //        // 更新任务状态
        //        wmsTask.TaskStatus = TaskStatusEnum.WANCHENG;
        //        wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.W;
        //        wmsTask.IsRead = false;
        //        await _wmsTaskRep.UpdateAsync(wmsTask);

        //        // 更新单据明细状态为完成、更新托盘编号、更新库位编号
        //        var wmsOrderDetails = await _wmsOrderDetailsRep.Where(z => z.Id == wmsTask.OrderDetailsId).ProjectToType<WmsOrderDetails>().FirstOrDefaultAsync();
        //        if (wmsOrderDetails != null)
        //        {
        //            wmsOrderDetails.ContainerCode = wmsTask.ContainerCode;
        //            wmsOrderDetails.PlaceCode = wmsPlace.PlaceCode;
        //            wmsOrderDetails.OrderStatus = OrderDetailsStatusEnum.WANCHENG;
        //            await _wmsOrderDetailsRep.UpdateNowAsync(wmsOrderDetails);
        //        }
        //        // 单据明细完成总数
        //        var orderDetailsCount = (await _wmsOrderDetailsRep.DetachedEntities
        //            .Where(z => z.OrderId == wmsOrderDetails.WareOrder.Id && z.OrderStatus == OrderDetailsStatusEnum.WANCHENG).ToListAsync()).Count;

        //        if (orderDetailsCount == wmsOrderDetails.WareOrder.OrderQuantityTotal)
        //        {
        //            wmsOrderDetails.WareOrder.OrderStatus = OrderStatusEnum.WANCHENG;
        //            await _wmsOrderRep.UpdateAsync(wmsOrderDetails.WareOrder);
        //        }

        //        // 更新库位状态为存货
        //        wmsPlace.PlaceStatus = PlaceStatus.CUNHUO;
        //        await _wmsPlaceRep.UpdateAsync(wmsPlace);

        //        // 更新托盘状态为“库位”
        //        wmsContainer.ContainerStatus = ContainerStatus.KUWEI;
        //        await _wmsContainerRep.UpdateAsync(wmsContainer);

        //        // 物料与托盘关系
        //        var wmsMaterialContainer = await _wmsMaterialContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode
        //        && z.MaterialNo == wmsOrderDetails.MaterialNo && z.BindStatus == CommonStatus.ENABLE);

        //        // 托盘与库位关系
        //        var wmsContainerPlace = new WmsContainerPlace()
        //        {
        //            PlaceId = wmsPlace.Id,
        //            PlaceCode = wmsPlace.PlaceCode,
        //            ContainerId = wmsContainer.Id,
        //            ContainerCode = wmsContainer.ContainerCode,
        //            ContainerPlaceStatus = CommonStatus.ENABLE
        //        };
        //        await _wmsContainerPlaceRep.InsertAsync(wmsContainerPlace);

        //        // 添加库存
        //        var StockModel = await _wmsMaterialStockRep.Where(p => p.ContainerCode == wmsTask.ContainerCode
        //        && p.MaterialNo == wmsOrderDetails.MaterialNo && p.MaterialBatch == wmsOrderDetails.Batch).FirstOrDefaultAsync();
        //        if (StockModel != null)
        //        {
        //            StockModel.MaterialDensity = wmsOrderDetails.MaterialDensity;
        //            StockModel.PlaceCode = wmsTask.ToPlace;
        //            StockModel.AreaId = wmsPlace.AreaId;
        //            StockModel.StockNumber = wmsOrderDetails.OrderQuantity;
        //            await _wmsMaterialStockRep.UpdateAsync(StockModel);
        //        }
        //        else
        //        {
        //            StockModel = new WmsMaterialStock()
        //            {
        //                MaterialNo = wmsOrderDetails.MaterialNo,
        //                MaterialType = wmsOrderDetails.MaterialType,
        //                MaterialName = "N/A",
        //                Long = wmsOrderDetails.Long,
        //                Wide = wmsOrderDetails.Wide,
        //                High = wmsOrderDetails.High,
        //                MaterialSpec = wmsOrderDetails.Long + "*" + wmsOrderDetails.Wide + "*" + wmsOrderDetails.High,
        //                MaterialBatch = wmsOrderDetails.Batch,
        //                MaterialDensity = wmsOrderDetails.MaterialDensity,
        //                //InspectionMethod = item.WmsMaterial.InspectionMethod,
        //                //UnitType = item.WmsMaterial.UnitType,
        //                //UnitNo = item.WmsMaterial.UnitNo,
        //                StockNumber = wmsOrderDetails.OrderQuantity,
        //                PlaceCode = wmsTask.ToPlace,
        //                ContainerId = wmsContainer.Id,
        //                ContainerCode = wmsContainer.ContainerCode,
        //                AreaId = wmsPlace.AreaId,
        //            };
        //            await _wmsMaterialStockRep.InsertAsync(StockModel);
        //        }
        //    }
        //    else if (wmsTask.TaskType == TaskType.CHUKU) //出库任务
        //    {
        //        var taskStatusList = new List<TaskDodeviceStatusEnum> { TaskDodeviceStatusEnum.ZX_DDJ, TaskDodeviceStatusEnum.WC_DDJ };
        //        if (!taskStatusList.Contains(wmsTask.TaskDodeviceStatus)) throw Oops.Oh("只有堆垛机执行,堆垛机完成才能强制完成！");
        //        // 查询托盘信息
        //        var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode);
        //        if (wmsContainer == null) throw Oops.Oh("托盘信息不存在!");

        //        // 查询库位信息
        //        var wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(u => u.PlaceCode == wmsTask.SourcePlace);
        //        if (wmsPlace == null) throw Oops.Oh("库位信息不存在!");
        //        // 查询托盘与库位的关系
        //        var wmsContainerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(z => z.PlaceId == wmsPlace.Id && z.PlaceCode == wmsPlace.PlaceCode
        //        && z.ContainerCode == wmsTask.ContainerCode && z.ContainerPlaceStatus == CommonStatus.ENABLE);
        //        if (wmsContainerPlace != null)
        //        {
        //            // 禁用托盘库位关系
        //            wmsContainerPlace.ContainerPlaceStatus = CommonStatus.DELETED;
        //            await _wmsContainerPlaceRep.UpdateAsync(wmsContainerPlace);
        //        }
        //        // 根据任务表中的单据明细Id查询单据明细信息
        //        var wmsOrderDetails = await _wmsOrderDetailsRep.FirstOrDefaultAsync(z => z.Id == wmsTask.OrderDetailsId);

        //        wmsTask.TaskStatus = TaskStatusEnum.ZHIXINGZHONG;
        //        wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.ZX_RGV;
        //        wmsTask.IsRead = false;
        //        await _wmsTaskRep.UpdateAsync(wmsTask);


        //        // 查询是否已存在物料与托盘关系
        //        var wmsMaterialContainer = await _wmsMaterialContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode
        //        && z.MaterialNo == wmsOrderDetails.MaterialNo && z.BindStatus == CommonStatus.ENABLE);
        //        //入库时组盘信息逻辑删除
        //        if (wmsMaterialContainer != null)
        //        {
        //            wmsMaterialContainer.BindStatus = CommonStatus.DELETED;
        //            await _wmsMaterialContainerRep.UpdateAsync(wmsMaterialContainer);
        //            //新增出库绑定记录 正常
        //            var enable = new WmsMaterialContainer()
        //            {
        //                ContainerId = wmsContainer.Id,
        //                ContainerCode = wmsContainer.ContainerCode,
        //                MaterialId = YitIdHelper.NextId(), //系统生成的Id
        //                MaterialName = "N/A",
        //                MaterialNo = wmsMaterialContainer.MaterialNo,
        //                MaterialBatch = wmsMaterialContainer.MaterialBatch,
        //                MaterialDensity = wmsMaterialContainer.MaterialDensity,
        //                MaterialSpec = wmsOrderDetails.Long + "*" + wmsOrderDetails.Wide + "*" + wmsOrderDetails.High,
        //                BindQuantity = 1, //一个库位只有一个物料
        //                OrderNo = wmsMaterialContainer.OrderNo,
        //                OrderDetailsId = wmsMaterialContainer.OrderDetailsId,
        //                BindStatus = CommonStatus.ENABLE
        //            };
        //            await _wmsMaterialContainerRep.InsertAsync(enable);
        //        }
        //        //更新库存
        //        var stockModel = await _wmsMaterialStockRep.Where(p => p.ContainerCode == wmsTask.ContainerCode && p.PlaceCode == wmsTask.SourcePlace
        //        && p.MaterialNo == wmsOrderDetails.MaterialNo && p.MaterialBatch == wmsOrderDetails.Batch).FirstOrDefaultAsync();
        //        if (stockModel != null)
        //        {
        //            await _wmsMaterialStockRep.DeleteAsync(stockModel);
        //        }
        //        // 更新库位状态为“空闲”
        //        wmsPlace.PlaceStatus = PlaceStatus.KONGXIAN;
        //        await _wmsPlaceRep.UpdateAsync(wmsPlace);

        //        //更新托盘状态为“空闲”
        //        wmsContainer.ContainerStatus = ContainerStatus.KOUXIAN;
        //        await _wmsContainerRep.UpdateAsync(wmsContainer);
        //    }
        //    else //移库任务
        //    {
        //        var taskStatusList = new List<TaskDodeviceStatusEnum> { TaskDodeviceStatusEnum.ZX_DDJ, TaskDodeviceStatusEnum.WC_DDJ };
        //        if (!taskStatusList.Contains(wmsTask.TaskDodeviceStatus)) throw Oops.Oh("只有堆垛机执行,堆垛机完成才能强制完成！");
        //        // 查询托盘
        //        var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode);
        //        if (wmsContainer == null) throw Oops.Oh("托盘信息不存在!");

        //        wmsTask.TaskStatus = TaskStatusEnum.WANCHENG;
        //        wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.W;
        //        wmsTask.IsRead = false;
        //        // 起点库位信息
        //        var SourcePlace = await _wmsPlaceRep.Where(z => z.PlaceCode == wmsTask.SourcePlace).FirstOrDefaultAsync();
        //        SourcePlace.PlaceStatus = PlaceStatus.KONGXIAN;
        //        await _wmsPlaceRep.UpdateAsync(SourcePlace);
        //        //目标库位信息
        //        var ToPlace = await _wmsPlaceRep.Where(z => z.PlaceCode == wmsTask.ToPlace).FirstOrDefaultAsync();
        //        ToPlace.PlaceStatus = PlaceStatus.CUNHUO;
        //        await _wmsPlaceRep.UpdateAsync(ToPlace);
        //        //托盘库位关系表
        //        var wmsContainerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(z => z.PlaceId == SourcePlace.Id && z.PlaceCode == SourcePlace.PlaceCode
        //        && z.ContainerCode == wmsTask.ContainerCode && z.ContainerPlaceStatus == CommonStatus.ENABLE);
        //        wmsContainerPlace.ContainerPlaceStatus = CommonStatus.DELETED;
        //        await _wmsContainerPlaceRep.UpdateAsync(wmsContainerPlace);
        //        await _wmsContainerPlaceRep.InsertAsync(new WmsContainerPlace()
        //        {
        //            PlaceId = ToPlace.Id,
        //            PlaceCode = ToPlace.PlaceCode,
        //            ContainerId = wmsContainer.Id,
        //            ContainerCode = wmsContainer.ContainerCode,
        //            ContainerPlaceStatus = CommonStatus.ENABLE
        //        });
        //        //库存库位更新
        //        var stockModel = await _wmsMaterialStockRep.Where(p => p.ContainerCode == wmsTask.ContainerCode && p.PlaceCode == SourcePlace.PlaceCode).FirstOrDefaultAsync();
        //        if (stockModel != null)
        //        {
        //            stockModel.PlaceCode = ToPlace.PlaceCode;
        //        }
        //    }
        //}


        /// <summary>
        /// 取消任务
        /// </summary>
        /// <returns></returns>
        [HttpPost("CancelTask")]
        [UnitOfWork]
        [AllowAnonymous]
        public async Task CancelTask([FromBody] FinishTaskInput input)
        {
            var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.TaskNo == input.TaskNo);
            if (wmsTask == null) throw Oops.Oh("任务不存在！");
            if (wmsTask.TaskStatus == TaskStatusEnum.WANCHENG) throw Oops.Oh("任务已完成，取消失败！");
            if (wmsTask.TaskType == TaskType.RUKU) // 入库任务
            {
                //var statusList = new List<TaskDodeviceStatusEnum> {TaskDodeviceStatusEnum.ZX_RSSX, TaskDodeviceStatusEnum.WC_RSSX,TaskDodeviceStatusEnum.WZX };
                //if (!statusList.Contains(wmsTask.TaskDodeviceStatus)) throw Oops.Oh("只有入库输送线执行,入库输送线完成或者设备未执行才能强制取消！");
                //更新单据明细状态为未执行、更新托盘编号、更新库位编号
                var wmsOrderDetails = await _wmsOrderDetailsRep.Where(z => z.Id == wmsTask.OrderDetailsId).ProjectToType<WmsOrderDetails>().FirstOrDefaultAsync();
                if (wmsOrderDetails != null)
                {
                    wmsOrderDetails.OrderStatus = OrderDetailsStatusEnum.WEIZHIXING;
                    await _wmsOrderDetailsRep.UpdateNowAsync(wmsOrderDetails);
                }
                //查询库位
                var wmsPlace = await _wmsPlaceRep.DetachedEntities.Where(u => u.PlaceCode == wmsTask.ToPlace && u.WmsArea.WorkShopType == LesWorkShopType.FAPAOCHEJIAN).ProjectToType<WmsPlace>().FirstOrDefaultAsync();
                if (wmsPlace != null)
                {
                    // 更新库位状态为空闲
                    wmsPlace.PlaceStatus = PlaceStatus.KONGXIAN;
                    await _wmsPlaceRep.UpdateAsync(wmsPlace);
                }
                var materialContainer = await _wmsMaterialContainerRep.Where(p => p.ContainerCode == wmsTask.ContainerCode && p.BindStatus == CommonStatus.ENABLE).FirstOrDefaultAsync();
                if (materialContainer != null)
                {
                    await _wmsMaterialContainerRep.DeleteNowAsync(materialContainer);
                }
                // 查询托盘
                var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode);
                if (wmsContainer != null)
                {
                    wmsContainer.ContainerStatus = ContainerStatus.KOUXIAN;
                    await _wmsContainerRep.UpdateAsync(wmsContainer);
                }
                // 更新任务状态
                wmsTask.TaskStatus = TaskStatusEnum.WEIZHIXING;
                wmsTask.IsRead = false;
                wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.WZX;
                wmsTask.ToPlace = "";
                await _wmsTaskRep.UpdateAsync(wmsTask);
            }
            else if (wmsTask.TaskType == TaskType.CHUKU) //出库任务
            {
                var statusList = new List<TaskDodeviceStatusEnum> { TaskDodeviceStatusEnum.WZX, TaskDodeviceStatusEnum.ZX_DDJ };
                if (!statusList.Contains(wmsTask.TaskDodeviceStatus)) throw Oops.Oh("只有堆垛机执行中或设备未执行才能强制取消！");
                // 查询库位信息
                var wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(u => u.PlaceCode == wmsTask.SourcePlace);
                if (wmsPlace == null) throw Oops.Oh("库位信息不存在!");
                // 查询托盘与库位的关系
                var wmsContainerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(z => z.PlaceId == wmsPlace.Id && z.PlaceCode == wmsPlace.PlaceCode
                && z.ContainerCode == wmsTask.ContainerCode && z.ContainerPlaceStatus == CommonStatus.ENABLE);
                if (wmsContainerPlace == null) throw Oops.Oh("库位容器关系不存在!");
                // 根据任务表中的单据明细Id查询单据明细信息
                var wmsOrderDetails = await _wmsOrderDetailsRep.FirstOrDefaultAsync(z => z.Id == wmsTask.OrderDetailsId);
                //修改单据明细,任务状态,设备任务状态为未执行
                wmsOrderDetails.OrderStatus = OrderDetailsStatusEnum.WEIZHIXING;
                await _wmsOrderDetailsRep.UpdateNowAsync(wmsOrderDetails);
                wmsTask.TaskStatus = TaskStatusEnum.WEIZHIXING;
                wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.WZX;
                await _wmsTaskRep.UpdateAsync(wmsTask);
                // 更新库位状态为存货
                wmsPlace.PlaceStatus = PlaceStatus.CUNHUO;
                await _wmsPlaceRep.UpdateAsync(wmsPlace);
            }
            else //移库任务
            {
                var statusList = new List<TaskDodeviceStatusEnum> { TaskDodeviceStatusEnum.WZX, TaskDodeviceStatusEnum.ZX_DDJ };
                if (!statusList.Contains(wmsTask.TaskDodeviceStatus)) throw Oops.Oh("只有堆垛机执行中，设备未执行才能强制取消！");
                // 查询托盘
                var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode);
                if (wmsContainer == null) throw Oops.Oh("托盘信息不存在!");
                //删除任务
                await _wmsTaskRep.DeleteAsync(wmsTask);
                // 起点库位信息
                var SourcePlace = await _wmsPlaceRep.Where(z => z.PlaceCode == wmsTask.SourcePlace).FirstOrDefaultAsync();
                SourcePlace.PlaceStatus = PlaceStatus.CUNHUO;
                await _wmsPlaceRep.UpdateAsync(SourcePlace);
                //目标库位信息
                var ToPlace = await _wmsPlaceRep.Where(z => z.PlaceCode == wmsTask.ToPlace).FirstOrDefaultAsync();
                ToPlace.PlaceStatus = PlaceStatus.KONGXIAN;
                await _wmsPlaceRep.UpdateAsync(ToPlace);
            }
        }


        /// <summary>
        /// wcs读取接口判断物料是否组盘出库 true代表已经组盘出库
        /// </summary>
        /// <returns></returns>
        [HttpGet("CheckPack")]
        [AllowAnonymous]
        [NonAction]
        public async Task<bool> CheckPack()
        {
            var packList = await _lesPackWarehouseRep.Where(p => p.LesPackState == LesPackState.WEICHUKU).Select(n => n.OrderNo).Distinct().ToListAsync();
            if (packList.Count >= 2) return false;
            else return true;
        }

        /// <summary>
        /// 设备报警信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("AddDeviceWaring")]
        [AllowAnonymous]
        [NonAction]
        public async Task AddDeviceWaring(AddDeviceWaringInput input)
        {
            //判断wcsid是否存在
            var lesDeviceWaring = await _lesDeviceWaringRep.FirstOrDefaultAsync(u => u.WcsId == input.WcsId);
            if (lesDeviceWaring != null)
            {
                await _lesDeviceWaringRep.UpdateAsync(lesDeviceWaring);
            }
            else
            {
                lesDeviceWaring = input.Adapt<LesDeviceWaring>();
                await _lesDeviceWaringRep.InsertAsync(lesDeviceWaring);
            }
        }

        #region  公用方法
        /// <summary>
        /// 根据巷道获取外侧第一排
        /// </summary>
        /// <param name="Aisle"></param>
        /// <returns></returns>
        [NonAction]
        public int GetOneRowByAisle(int Aisle)
        {
            if (Aisle >= 7)
            {
                return 1;
            }
            return (Aisle - 1) * 4 + 1;
        }
        /// <summary>
        /// 根据巷道获取内侧第二排
        /// </summary>
        /// <param name="Aisle"></param>
        /// <returns></returns>
        [NonAction]
        public int GetTwoRowByAisle(int Aisle)
        {
            if (Aisle >= 7)
            {
                return 2;
            }
            return (Aisle - 1) * 4 + 2;
        }
        /// <summary>
        /// 根据巷道获取外侧第二排
        /// </summary>
        /// <param name="Aisle"></param>
        /// <returns></returns>
        [NonAction]
        public int GetThreeRowByAisle(int Aisle)
        {
            if (Aisle >= 7)
            {
                return 3;
            }
            return (Aisle - 1) * 4 + 3;
        }
        /// <summary>
        /// 根据巷道获取外侧第一排
        /// </summary>
        /// <param name="Aisle"></param>
        /// <returns></returns>
        [NonAction]
        public int GetFourRowByAisle(int Aisle)
        {
            if (Aisle >= 7)
            {
                return 4;
            }
            return (Aisle - 1) * 4 + 4;
        }
        #endregion
    }
}
